package com.whfc.common.third.uni.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.third.uni.UniApi;
import com.whfc.common.third.uni.UniProperties;
import com.whfc.common.third.uni.entity.*;
import com.whfc.common.util.HttpUtil;
import com.whfc.common.util.MD5Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 宇视科技监控摄像头API实现类
 */
@Component
public class UniApiImpl implements UniApi {

    private static final Logger logger = LoggerFactory.getLogger(UniApiImpl.class);

    private final UniProperties uniProperties;

    // API路径常量
    private static final String ACCESS_TOKEN_URL = "/openAPI/oauth/v1/token/get";
    private static final String ORGANIZATION_SEARCH_URL = "/openAPI/resource/v1/organizations/search";
    private static final String RESOURCE_SEARCH_URL = "/openAPI/resource/v1/resources/search";
    private static final String CAMERA_RECORD_SEARCH_URL = "/openAPI/video/v1/camera/record/search";
    private static final String CAMERA_PLAYBACK_URL_GET = "/openAPI/video/v1/camera/playbackUrl/get";
    private static final String CAMERA_PREVIEW_URL_GET = "/openAPI/video/v1/camera/previewUrl/get";
    private static final String PRESET_SEARCH_URL = "/openAPI/video/v1/camera/ptz/presets/search";
    private static final String PRESET_ADD_URL = "/openAPI/video/v1/camera/ptz/preset/add";
    private static final String PRESET_GOTO_URL = "/openAPI/video/v1/camera/ptz/preset/goto";
    private static final String PRESET_DELETE_URL = "/openAPI/video/v1/camera/ptz/preset/delete";
    private static final String EVENT_SUBSCRIPTION_URL = "/openAPI/event/v1/subscription/subscribe";
    private static final String EVENT_UNSUBSCRIPTION_URL = "/openAPI/event/v1/subscription/unsubscribe";

    public UniApiImpl(UniProperties uniProperties) {
        this.uniProperties = uniProperties;
    }

    @Override
    public String getAccessToken() throws BizException {
        logger.info("获取宇视科技访问令牌，username:{}", uniProperties.getUsername());

        try {
            // 构建请求URL
            String url = buildBaseUrl() + ACCESS_TOKEN_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("clientId", uniProperties.getUsername());
            requestBody.put("clientSecret", MD5Util.md5Encode(uniProperties.getPassword()));
            requestBody.put("grantType", "password");

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), null,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("获取宇视科技访问令牌响应: {}", response);

            // 解析响应
            JSONObject jsonResponse = JSON.parseObject(response);
            if (jsonResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "获取访问令牌失败，响应数据为空");
            }

            Integer code = jsonResponse.getInteger("code");
            if (code == null || code != 0) {
                String msg = jsonResponse.getString("msg");
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        msg != null ? msg : "获取访问令牌失败");
            }

            JSONObject data = jsonResponse.getJSONObject("data");
            if (data == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "获取访问令牌失败，响应数据异常");
            }

            String accessToken = data.getString("accessToken");
            if (accessToken == null || accessToken.isEmpty()) {
                throw new BizException(ResultEnum.FAILURE.getCode(), "获取访问令牌失败，令牌为空");
            }

            return accessToken;
        } catch (BizException e) {
            logger.error("获取宇视科技访问令牌业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("获取宇视科技访问令牌异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "获取宇视科技访问令牌失败: " + e.getMessage());
        }
    }

    @Override
    public OrganizationSearchResponse searchOrganizations(Integer pageNo, Integer pageSize) throws BizException {
        logger.info("查询宇视科技组织，pageNo:{}, pageSize:{}", pageNo, pageSize);

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + ORGANIZATION_SEARCH_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("pageNo", pageNo != null ? pageNo : 1);
            requestBody.put("pageSize", pageSize != null ? pageSize : 20);

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("查询宇视科技组织响应: {}", response);

            // 解析响应
            OrganizationSearchResponse searchResponse = JSON.parseObject(response, OrganizationSearchResponse.class);
            if (searchResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "查询组织失败，响应数据为空");
            }

            if (!searchResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        searchResponse.getMsg() != null ? searchResponse.getMsg() : "查询组织失败");
            }

            return searchResponse;
        } catch (BizException e) {
            logger.error("查询宇视科技组织业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("查询宇视科技组织异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "查询宇视科技组织失败: " + e.getMessage());
        }
    }

    @Override
    public ResourceSearchResponse searchResources(String resourceType, Integer pageNo, Integer pageSize)
            throws BizException {
        logger.info("查询宇视科技资源，resourceType:{}, pageNo:{}, pageSize:{}", resourceType, pageNo, pageSize);

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + RESOURCE_SEARCH_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("resourceType", resourceType != null ? resourceType : "camera");
            requestBody.put("pageNo", pageNo != null ? pageNo : 1);
            requestBody.put("pageSize", pageSize != null ? pageSize : 20);

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("查询宇视科技资源响应: {}", response);

            // 解析响应
            ResourceSearchResponse searchResponse = JSON.parseObject(response, ResourceSearchResponse.class);
            if (searchResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "查询资源失败，响应数据为空");
            }

            if (!searchResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        searchResponse.getMsg() != null ? searchResponse.getMsg() : "查询资源失败");
            }

            return searchResponse;
        } catch (BizException e) {
            logger.error("查询宇视科技资源业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("查询宇视科技资源异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "查询宇视科技资源失败: " + e.getMessage());
        }
    }

    @Override
    public CameraRecordSearchResponse searchCameraRecords(String channelIndexCode, String beginTime,
            String endTime, Integer recordLocation,
            Integer streamType, Integer pageStart,
            Integer pageSize) throws BizException {
        logger.info("查询宇视科技监控点录像片段，channelIndexCode:{}, beginTime:{}, endTime:{}",
                channelIndexCode, beginTime, endTime);

        // 参数校验
        if (channelIndexCode == null || channelIndexCode.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "通道编码不能为空");
        }
        if (beginTime == null || beginTime.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "开始时间不能为空");
        }
        if (endTime == null || endTime.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "结束时间不能为空");
        }

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + CAMERA_RECORD_SEARCH_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("channelIndexCode", channelIndexCode);
            requestBody.put("beginTime", beginTime);
            requestBody.put("endTime", endTime);
            requestBody.put("recordLocation", recordLocation != null ? recordLocation : 1);
            requestBody.put("streamType", streamType != null ? streamType : 1);
            requestBody.put("pageStart", pageStart != null ? pageStart : 1);
            requestBody.put("pageSize", pageSize != null ? pageSize : 200);

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("查询宇视科技监控点录像片段响应: {}", response);

            // 解析响应
            CameraRecordSearchResponse searchResponse = JSON.parseObject(response, CameraRecordSearchResponse.class);
            if (searchResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "查询监控点录像片段失败，响应数据为空");
            }

            if (!searchResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        searchResponse.getMsg() != null ? searchResponse.getMsg() : "查询监控点录像片段失败");
            }

            return searchResponse;
        } catch (BizException e) {
            logger.error("查询宇视科技监控点录像片段业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("查询宇视科技监控点录像片段异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "查询宇视科技监控点录像片段失败: " + e.getMessage());
        }
    }

    @Override
    public CameraPlaybackUrlResponse getCameraPlaybackUrl(String channelIndexCode, String beginTime,
            String endTime) throws BizException {
        logger.info("获取宇视科技监控点取流回放URL，channelIndexCode:{}, beginTime:{}, endTime:{}",
                channelIndexCode, beginTime, endTime);

        // 参数校验
        if (channelIndexCode == null || channelIndexCode.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "通道编码不能为空");
        }
        if (beginTime == null || beginTime.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "开始时间不能为空");
        }
        if (endTime == null || endTime.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "结束时间不能为空");
        }

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + CAMERA_PLAYBACK_URL_GET;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("channelIndexCode", channelIndexCode);
            requestBody.put("beginTime", beginTime);
            requestBody.put("endTime", endTime);

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("获取宇视科技监控点取流回放URL响应: {}", response);

            // 解析响应
            CameraPlaybackUrlResponse urlResponse = JSON.parseObject(response, CameraPlaybackUrlResponse.class);
            if (urlResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "获取监控点取流回放URL失败，响应数据为空");
            }

            if (!urlResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        urlResponse.getMsg() != null ? urlResponse.getMsg() : "获取监控点取流回放URL失败");
            }

            return urlResponse;
        } catch (BizException e) {
            logger.error("获取宇视科技监控点取流回放URL业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("获取宇视科技监控点取流回放URL异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "获取宇视科技监控点取流回放URL失败: " + e.getMessage());
        }
    }

    @Override
    public CameraPreviewUrlResponse getCameraPreviewUrl(String channelIndexCode, Integer transMode,
            String protocol, Integer streamType) throws BizException {
        logger.info("获取宇视科技监控点预览起流URL，channelIndexCode:{}, transMode:{}, protocol:{}, streamType:{}",
                channelIndexCode, transMode, protocol, streamType);

        // 参数校验
        if (channelIndexCode == null || channelIndexCode.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "通道编码不能为空");
        }

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + CAMERA_PREVIEW_URL_GET;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("channelIndexCode", channelIndexCode);
            requestBody.put("transMode", transMode != null ? transMode : 2);
            requestBody.put("protocol", protocol != null ? protocol : "rtsp");
            requestBody.put("streamType", streamType != null ? streamType : 1);

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("获取宇视科技监控点预览起流URL响应: {}", response);

            // 解析响应
            CameraPreviewUrlResponse previewResponse = JSON.parseObject(response, CameraPreviewUrlResponse.class);
            if (previewResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "获取监控点预览起流URL失败，响应数据为空");
            }

            if (!previewResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        previewResponse.getMsg() != null ? previewResponse.getMsg() : "获取监控点预览起流URL失败");
            }

            return previewResponse;
        } catch (BizException e) {
            logger.error("获取宇视科技监控点预览起流URL业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("获取宇视科技监控点预览起流URL异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "获取宇视科技监控点预览起流URL失败: " + e.getMessage());
        }
    }

    @Override
    public PresetSearchResponse searchPresets(String channelIndexCode) throws BizException {
        logger.info("查询宇视科技预置位，channelIndexCode:{}", channelIndexCode);

        // 参数校验
        if (channelIndexCode == null || channelIndexCode.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "通道编码不能为空");
        }

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + PRESET_SEARCH_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("channelIndexCode", channelIndexCode);

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("查询宇视科技预置位响应: {}", response);

            // 解析响应
            PresetSearchResponse searchResponse = JSON.parseObject(response, PresetSearchResponse.class);
            if (searchResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "查询预置位失败，响应数据为空");
            }

            if (!searchResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        searchResponse.getMsg() != null ? searchResponse.getMsg() : "查询预置位失败");
            }

            return searchResponse;
        } catch (BizException e) {
            logger.error("查询宇视科技预置位业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("查询宇视科技预置位异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "查询宇视科技预置位失败: " + e.getMessage());
        }
    }

    @Override
    public BaseResponse addPreset(String channelIndexCode, Integer presetIndex, String presetName) throws BizException {
        logger.info("设置宇视科技预置位，channelIndexCode:{}, presetIndex:{}, presetName:{}",
                channelIndexCode, presetIndex, presetName);

        // 参数校验
        if (channelIndexCode == null || channelIndexCode.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "通道编码不能为空");
        }
        if (presetIndex == null || presetIndex < 1 || presetIndex > 255) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "预置位编号必须在1-255之间");
        }
        if (presetName == null || presetName.isEmpty() || presetName.length() > 64) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "预置位名称不能为空且长度不能超过64个字符");
        }

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + PRESET_ADD_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("channelIndexCode", channelIndexCode);
            requestBody.put("presetIndex", presetIndex);
            requestBody.put("presetName", presetName);

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("设置宇视科技预置位响应: {}", response);

            // 解析响应
            BaseResponse addResponse = JSON.parseObject(response, BaseResponse.class);
            if (addResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "设置预置位失败，响应数据为空");
            }

            if (!addResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        addResponse.getMsg() != null ? addResponse.getMsg() : "设置预置位失败");
            }

            return addResponse;
        } catch (BizException e) {
            logger.error("设置宇视科技预置位业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("设置宇视科技预置位异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "设置宇视科技预置位失败: " + e.getMessage());
        }
    }

    @Override
    public BaseResponse gotoPreset(String channelIndexCode, Integer presetIndex) throws BizException {
        logger.info("调用宇视科技预置位，channelIndexCode:{}, presetIndex:{}", channelIndexCode, presetIndex);

        // 参数校验
        if (channelIndexCode == null || channelIndexCode.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "通道编码不能为空");
        }
        if (presetIndex == null || presetIndex < 1 || presetIndex > 255) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "预置位编号必须在1-255之间");
        }

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + PRESET_GOTO_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("channelIndexCode", channelIndexCode);
            requestBody.put("presetIndex", presetIndex);

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("调用宇视科技预置位响应: {}", response);

            // 解析响应
            BaseResponse gotoResponse = JSON.parseObject(response, BaseResponse.class);
            if (gotoResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "调用预置位失败，响应数据为空");
            }

            if (!gotoResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        gotoResponse.getMsg() != null ? gotoResponse.getMsg() : "调用预置位失败");
            }

            return gotoResponse;
        } catch (BizException e) {
            logger.error("调用宇视科技预置位业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("调用宇视科技预置位异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "调用宇视科技预置位失败: " + e.getMessage());
        }
    }

    @Override
    public BaseResponse deletePreset(String channelIndexCode, Integer presetIndex) throws BizException {
        logger.info("删除宇视科技预置位，channelIndexCode:{}, presetIndex:{}", channelIndexCode, presetIndex);

        // 参数校验
        if (channelIndexCode == null || channelIndexCode.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "通道编码不能为空");
        }
        if (presetIndex == null || presetIndex < 1 || presetIndex > 255) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "预置位编号必须在1-255之间");
        }

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + PRESET_DELETE_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("channelIndexCode", channelIndexCode);
            requestBody.put("presetIndex", presetIndex);

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("删除宇视科技预置位响应: {}", response);

            // 解析响应
            BaseResponse deleteResponse = JSON.parseObject(response, BaseResponse.class);
            if (deleteResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "删除预置位失败，响应数据为空");
            }

            if (!deleteResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        deleteResponse.getMsg() != null ? deleteResponse.getMsg() : "删除预置位失败");
            }

            return deleteResponse;
        } catch (BizException e) {
            logger.error("删除宇视科技预置位业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("删除宇视科技预置位异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "删除宇视科技预置位失败: " + e.getMessage());
        }
    }

    @Override
    public EventSubscriptionResponse subscribeEvent(String eventDest, String[] eventTypes) throws BizException {
        logger.info("宇视科技事件订阅，eventDest:{}, eventTypes:{}", eventDest, eventTypes);

        // 参数校验
        if (eventDest == null || eventDest.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "事件接收地址不能为空");
        }

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + EVENT_SUBSCRIPTION_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("eventDest", eventDest);
            if (eventTypes != null && eventTypes.length > 0) {
                requestBody.put("eventTypes", eventTypes);
            }

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("宇视科技事件订阅响应: {}", response);

            // 解析响应
            EventSubscriptionResponse subscriptionResponse = JSON.parseObject(response,
                    EventSubscriptionResponse.class);
            if (subscriptionResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "事件订阅失败，响应数据为空");
            }

            if (!subscriptionResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        subscriptionResponse.getMsg() != null ? subscriptionResponse.getMsg() : "事件订阅失败");
            }

            return subscriptionResponse;
        } catch (BizException e) {
            logger.error("宇视科技事件订阅业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("宇视科技事件订阅异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "宇视科技事件订阅失败: " + e.getMessage());
        }
    }

    @Override
    public EventSubscriptionResponse unsubscribeEvent(String eventDest, String[] eventTypes) throws BizException {
        logger.info("宇视科技取消事件订阅，eventDest:{}, eventTypes:{}", eventDest, eventTypes);

        // 参数校验
        if (eventDest == null || eventDest.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "事件接收地址不能为空");
        }

        try {
            String accessToken = getAccessToken();
            String url = buildBaseUrl() + EVENT_UNSUBSCRIPTION_URL;

            // 构建请求体
            JSONObject requestBody = new JSONObject();
            requestBody.put("eventDest", eventDest);
            if (eventTypes != null && eventTypes.length > 0) {
                requestBody.put("eventTypes", eventTypes);
            }

            // 设置请求头
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", accessToken);

            // 发送POST请求
            String response = HttpUtil.doPost(url, requestBody.toJSONString(), headers,
                    uniProperties.getConnectTimeout(), uniProperties.getReadTimeout());

            logger.info("宇视科技取消事件订阅响应: {}", response);

            // 解析响应
            EventSubscriptionResponse subscriptionResponse = JSON.parseObject(response,
                    EventSubscriptionResponse.class);
            if (subscriptionResponse == null) {
                throw new BizException(ResultEnum.NETWORK_ERROR.getCode(), "取消事件订阅失败，响应数据为空");
            }

            if (!subscriptionResponse.isSuccess()) {
                throw new BizException(ResultEnum.FAILURE.getCode(),
                        subscriptionResponse.getMsg() != null ? subscriptionResponse.getMsg() : "取消事件订阅失败");
            }

            return subscriptionResponse;
        } catch (BizException e) {
            logger.error("宇视科技取消事件订阅业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("宇视科技取消事件订阅异常: {}", e.getMessage(), e);
            throw new BizException(ResultEnum.NETWORK_ERROR.getCode(),
                    "宇视科技取消事件订阅失败: " + e.getMessage());
        }
    }

    /**
     * 构建基础URL
     */
    private String buildBaseUrl() {
        return "http://" + uniProperties.getIp() + ":" + uniProperties.getPort();
    }

}